package com.leyou.item.service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.leyou.common.enums.ExceptionEnum;
import com.leyou.common.exception.LyException;
import com.leyou.common.utils.BeanHelper;
import com.leyou.common.vo.PageResult;
import com.leyou.item.dto.SkuDTO;
import com.leyou.item.dto.SpuDTO;
import com.leyou.item.dto.SpuDetailDTO;
import com.leyou.item.entity.Category;
import com.leyou.item.entity.Sku;
import com.leyou.item.entity.Spu;
import com.leyou.item.entity.SpuDetail;
import com.leyou.item.mapper.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import tk.mybatis.mapper.entity.Example;


import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import static com.leyou.common.constants.MQConstants.Exchange.ITEM_EXCHANGE_NAME;
import static com.leyou.common.constants.MQConstants.RoutingKey.ITEM_DOWN_KEY;
import static com.leyou.common.constants.MQConstants.RoutingKey.ITEM_UP_KEY;

@Service
public class GoodsService {

    @Autowired
    private SpuMapper spuMapper;

    @Autowired
    private CategoryMapper categoryMapper;

    @Autowired
    private BrandMapper brandMapper;

    @Autowired
    private SpuDetailMapper spuDetailMapper;

    @Autowired
    private SkuMapper skuMapper;

    @Autowired
    private AmqpTemplate amqpTemplate;

    /*
     * @User Administrator
     * @Description //TODO  商品查询列表
     * @Date 9:43 2019/8/13 0013
     * @Param
     * @return
     **/
    public PageResult<SpuDTO> querySpuByPage(Integer page, Integer rows, Boolean saleable, String key) {

        //创建查询条件对象
        Example example = new Example(Spu.class);
        Example.Criteria criteria = example.createCriteria();
        // 封装key   (搜索条件过滤 )
        if (StringUtils.isNotBlank(key)) {
            criteria.andLike("name", "%" + key + "%");
        }
        //封装saleable  (上下架过滤)
        if (saleable != null) {
            criteria.andEqualTo("saleable", saleable);
        }

        //默认按时间排序
        example.setOrderByClause("update_time DESC");

        // 分页第一步:  封装分页对象
        PageHelper.startPage(page, rows);
        //分页第二步: 封装分页条件
        List<Spu> list = spuMapper.selectByExample(example);
        if (CollectionUtils.isEmpty(list)) {
            throw new LyException(ExceptionEnum.GOODS_NOT_FOUND);
        }
        //分页第三步: 封装pagehelper 的分页对象
        PageInfo<Spu> info = new PageInfo<>(list);


        //DTO装换
        List<SpuDTO> spuDTOS = BeanHelper.copyWithCollection(list, SpuDTO.class);

        //对spuDTO中产品名称和分类名称进行赋值
        handleCategoryAndBrandName(spuDTOS);

        return new PageResult<>(info.getTotal(),info.getPages(),spuDTOS);

    }
    /*
     * @User Administrator
     * @Description //TODO  对上面一个方法的实现
     * @Date 9:43 2019/8/13 0013
     * @Param
     * @return
     **/
    private void handleCategoryAndBrandName(List<SpuDTO> spuDTOS) {
        spuDTOS.forEach(spuDTO ->{  //遍历spuDTO集合,变量为spuDTO
            //给 分类名称  categoryName赋值
            String categoryNameList = categoryMapper.selectByIdList(spuDTO.getCategoryIds())
                    .stream()      //把list 装换成流
                    .map(Category::getName)    //收集每一个对象中的name值
                    .collect(Collectors.joining("/"));    //把这些name拼接起来
            spuDTO.setCategoryName(categoryNameList);
            //给brandName赋值
            spuDTO.setBrandName(brandMapper.selectByPrimaryKey(spuDTO.getBrandId()).getName());
        });
    }

    /*
     * @User Administrator
     * @Description //TODO  对新增操作中的sku    查询sku
     * @Date 21:42 2019/8/12 0012
     * @Param
     * @return
     **/
    public void saveGoods(SpuDTO spuDTO) {
        try {
            //保存spu
            Spu spu = BeanHelper.copyProperties(spuDTO, Spu.class);
            //手动设置商品下架
            spu.setSaleable(false);
            spuMapper.insertSelective(spu);

            //保存spuDetail
            SpuDetailDTO spuDetailDTO = spuDTO.getSpuDetail();
            SpuDetail spuDetail = BeanHelper.copyProperties(spuDetailDTO, SpuDetail.class);
            //给id属性赋值
            spuDetail.setSpuId(spu.getId());
            spuDetailMapper.insertSelective(spuDetail);

            //保存sku
            //得到SkuDTO
            List<SkuDTO> skuDTOS = spuDTO.getSkus();
            List<Sku> skus = BeanHelper.copyWithCollection(skuDTOS, Sku.class);
            skus.forEach(sku -> {
                sku.setSpuId(spu.getId());
                sku.setCreateTime(new Date());
                sku.setUpdateTime(new Date());
            });
            skuMapper.insertList(skus);
        } catch (Exception e) {
            throw new LyException(ExceptionEnum.INSERT_OPERATION_FAIL);
        }
    }

    /*
     * @User Administrator
     * @Description //TODO   修改上下架状态
     * @Date 10:05 2019/8/13 0013
     * @Param
     * @return
     **/
    public void updateSpuSaleable(Long id, Boolean saleable) {
        try {
            //1.跟新spu  修改上下架
            Spu spu = new Spu();
            spu.setId(id);
            spu.setSaleable(saleable);
            spuMapper.updateByPrimaryKeySelective(spu);

            //2.跟新sku
            //封装要修改的内容
            Sku sku = new Sku();
            sku.setEnable(saleable);
            //封装修改条件
            Example example = new Example(Sku.class);
            example.createCriteria().andEqualTo("spuId", id);


            skuMapper.updateByExampleSelective(sku, example);

            //向交换机发型消息
            String key = saleable ? ITEM_UP_KEY : ITEM_DOWN_KEY;
            //使用spring是amqp发送消息
            amqpTemplate.convertAndSend(ITEM_EXCHANGE_NAME,key, id);

        } catch (Exception e) {
            throw new LyException(ExceptionEnum.UPDATE_OPERATION_FAIL);
        }

    }

    /*
     * @User Administrator
     * @Description //TODO  修改商品回显
     * @Date 11:14 2019/8/13 0013
     * @Param
     * @return
     **/
    public SpuDetailDTO querySpuDetailById(Long id) {
        SpuDetail spuDetail = spuDetailMapper.selectByPrimaryKey(id);
        if (spuDetail == null) {
            throw new LyException(ExceptionEnum.GOODS_NOT_FOUND);
        }
        return BeanHelper.copyProperties(spuDetail, SpuDetailDTO.class);
    }
    /*
     * @User Administrator
     * @Description //TODO  回显查询sku操作
     * @Date 11:14 2019/8/13 0013
     * @Param
     * @return
     **/
    public List<SkuDTO> findSkusBySpuId(Long id) {
        Sku sku = new Sku();
        sku.setSpuId(id);
        List<Sku> select = skuMapper.select(sku);
        if (CollectionUtils.isEmpty(select)) {
            throw new LyException(ExceptionEnum.GOODS_NOT_FOUND);
        }
        return BeanHelper.copyWithCollection(select, SkuDTO.class);
    }

    public void updateGoods(SpuDTO spuDTO) {
        try {
            //修改spu
            Spu spu = BeanHelper.copyProperties(spuDTO, Spu.class);
            spuMapper.updateByPrimaryKeySelective(spu);

            //修改Spudetail
            SpuDetailDTO spuDetailDTO = spuDTO.getSpuDetail();
            SpuDetail spuDetail = BeanHelper.copyProperties(spuDetailDTO, SpuDetail.class);
            spuDetailMapper.updateByPrimaryKeySelective(spuDetail);

            //删除原来当前spu下所有的sku
            Sku sku = new Sku();
            sku.setSpuId(spu.getId());
            skuMapper.delete(sku);

            //添加sku
            List<SkuDTO> skuDTOS = spuDTO.getSkus();
            List<Sku> skus = BeanHelper.copyWithCollection(skuDTOS, Sku.class);
            skus.forEach(sku1 -> {
                sku1.setSpuId(spu.getId());
                sku1.setCreateTime(new Date());
                sku1.setUpdateTime(new Date());
            });
            skuMapper.insertList(skus);
        } catch (Exception e) {
            throw new LyException(ExceptionEnum.UPDATE_OPERATION_FAIL);
        }
    }


    public SpuDTO querySpuById(Long id) {
        Long spuid = Long.valueOf(id);
        Spu spu = spuMapper.selectByPrimaryKey(spuid);
        if(spu==null){
            throw new LyException(ExceptionEnum.GOODS_NOT_FOUND);
        }
        SpuDTO spuDTO = BeanHelper.copyProperties(spu, SpuDTO.class);
        //根据spuId查询SpuDetail
        SpuDetailDTO spuDetailDTO = querySpuDetailById(spuid);
        spuDTO.setSpuDetail(spuDetailDTO);
        //根据spuId查询Sku集合
        List<SkuDTO> skuDTOS = findSkusBySpuId(spuid);
        spuDTO.setSkus(skuDTOS);
        return spuDTO;
    }
}
